package se.webbzon.boltzmann.game.object.spawner;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;

import se.webbzon.boltzmann.environment.AbstractEnvironment;
import se.webbzon.boltzmann.game.environment.GameEnvironment;
import se.webbzon.boltzmann.game.region.RegionObject;
import se.webbzon.boltzmann.game.sequence.Sequences;
import se.webbzon.oschi01.worldeditor.WorldStaticObjectDeflation;
import se.webbzon.oschi01.worldobject.WorldObject;

public abstract class AbstractSpawnerDeflation extends WorldStaticObjectDeflation implements RegionObject {
	
	private long id;
	
	private String key = "";

	/*============================================================
	Public Methods
	============================================================*/
	
	/** Creates a new empty abstract spawner deflation. **/
	public AbstractSpawnerDeflation(int deflationProperties,
									WorldObject[] dependencies) {
		super(deflationProperties, dependencies);
	}
	
	/** Creates a new abstract spawner deflation from 
	 * an existing spawner. **/
	public AbstractSpawnerDeflation(int deflationProperties,
									WorldObject[] dependencies,
									AbstractSpawner spawner) {
		super(deflationProperties, dependencies, spawner);
		this.id = spawner.getId();
		this.key = spawner.getKey();
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	@Override public long getId() {
		return id;
	}
	
	@Override public void setId(long id) {
		this.id = id;
	}
	
	/** Returns the name of the key used as assignment condition. **/
	public String getKey() {
		return key;
	}
	
	@Override public void inflate(ByteBuffer buff) {
		super.inflate(buff);
		
		// Read from buffer
		id = buff.getLong();
		byte[] keyData = new byte[buff.getShort()];
		buff.get(keyData, 0, keyData.length);
		
		// Decode string
		try {
			key = new String(keyData,"UTF-8");
		} catch (UnsupportedEncodingException e) {
			key = "";
		}
	}

	@Override public ByteBuffer deflate(int allocate) {
		// Encode string
		byte[] keyData;
		try {
			keyData = key.getBytes("UTF-8");
		} catch (UnsupportedEncodingException e) {
			keyData = new byte[0];
		}
		
		// Write to buffer
		ByteBuffer buff = super.deflate(allocate + 10 + keyData.length);
		buff.putLong(id);
		buff.putShort((short) keyData.length);
		buff.put(keyData);
		return buff;
	}
	
	/*============================================================
	Protected Methods
	============================================================*/
	
	/** Returns true if the spawner should spawn an entity
	 * upon creation and not the spawner object itself. **/
	protected boolean spawn(AbstractEnvironment env) {
		if (env.isDebugMode())
			return false;
		else if (env instanceof GameEnvironment) {
			GameEnvironment genv = (GameEnvironment) env;
			final boolean deactivated = genv.hasRegionPersistence(this);
			final String name = Sequences.withoutPrefix(key);
			if (deactivated)
				return false;
			else if (name.isEmpty())
				return true;
			else if (genv.getVariables().isAssigned(name)) {
				Object value = genv.getVariables().valueOf(name);
				return !value.equals(0.0) && !value.equals("");
			} else
				return false;
		} else
			return true;
	}

}
